Backend Architecture Design
I. Applied Technologies
1. Domain Driven Design
DDD là một cách tiếp cận để phát triển những phần mềm phức tạp thông qua sự kết nối chặt chẽ giữa việc triển khai ứng dụng với sự phát triển của mô hình kinh doanh. DDD tập trung vào khái niệm domain và bóc tách bài toán dựa trên các domain đó.
Ở đây mô hình DDD các phần logic xử lý khác nhau sẽ được cô lập ra khỏi các phần khác làm tăng tính Loose Coupling của ứng dụng và tính dễ đọc, dễ bảo trì cũng như ứng dụng khi có thay đổi logic của từng layer thì không ảnh hướng đến các layer khác.
Mô hình DDD gồm các lớp:
User Interface: Chịu trách nhiệm trình bày thông tin tới người sử dụng và thông dịch lệnh của người dùng. Có thể hiểu là các sự kiện xảy ra trên giao diện khi được trigger sẽ được dịch thành lệnh và xử lý ở các tầng dưới.
Applicatioin Layer: Tầng này được thiết kế khá mỏng (ít xử lý logic) phối hợp các hoạt động của ứng dụng. Nó không chứa logic nghiệp vụ. Nó không lưu giữ trạng thái của các đối tượng nghiệp vụ nhưng nó có thể giữ trạng thái một tiến trình của ứng dụng.
Domain Layer: Tầng này chứa thông tin về các lĩnh vực. Đây chính là trái tim của phần mềm. Trạng thái của đối tượng nghiệp vụ được giữ tại đây.
Infrastructure Layer: Tầng này đóng vai trò như một thư viện hỗ trợ cho tất cả các tầng còn lại. Nó cung cấp thông tin liên lạc giữa các lớp, cung cấp chức năng lưu trữ các đối tượng nghiệp vụ, chứa các thư viện hỗ trợ cho tầng giao diện người dùng...

2. Clean Architecture
Clean Architecture là một kiến trúc ứng dụng rất nổi tiếng dựa trên nguyên lý loại bỏ sự lệ thuộc giữa các đối tượng cũng như các layer trong ứng dụng.
Trong kiến trúc Clean Architecture bao gồm 4 layer được đại diện thông qua các vòng tròn đồng tâm. Các vòng tròn ở trong sẽ không hề biết gì về các vòng tròn bên ngoài.

Từ trong ra ngoài Clean Architecture sẽ bao gồm: Entities, Use Cases, Interface Adapters và Frameworks & Drivers.
Tuy nhiên, không phải một ứng dụng và sản phẩm công nghệ nào cũng đầy đủ 4 tầng Entities, Use Cases, Interface Adapters và Frameworks & Drivers. Chúng ta có thể linh động tăng hoặc giảm số tầng cho phù hợp. Trong thực tế, hầu hết các kỹ sư sẽ chỉ tham khảo kiến trúc này để có được các kiến trúc phù hợp hơn.
3. CQRS
CQRS là một pattern cho việc xử lý CRUD dữ liệu được viết tắt bởi Command Query Responsibility Segregation. Trong đó phân tách thành 2 vai trò:
- Command : là các thao tác ghi dữ liệu - WRITE
- Query : là các thao tác đọc dữ liệu - READ
CQRS yêu cầu tách biệt các method cho việc query hoặc writing cho 1 model:
- Query: select và trả về dữ liệu, nhưng không thay đổi trạng thái của hệ thống
- Command : thay đổi dữ liệu/thay đổi trạng thái hệ thống, nhưng không trả về dữ liệu

4. Microservices
Microservice là một kiếu kiến trúc phần mềm. Các module trong phần mềm này được chia thành các service rất nhỏ (microservice). Mỗi service này đều có một logic riêng, một trách nhiệm riêng và có thể được deploy riêng biệt. Khái niệm mircoservice đồng thời đề cập đến xu hướng tách biệt architecture ra thành các loose coupling service.

II. Critical Practices in Gcalls
1. Những đặc điểm DDD ở Gcalls
Trong kiến trúc Gcalls có một số đặc điểm được thiết kế dựa theo hướng tiếp cận của Domain Driven Design, chúng ta có thể lấy ví dụ ở việc phân tách các service backend, với mỗi service tương ứng một domain như:
- User - User Service.
- Customer - Customer Service.
- ...
Domain Driven Design cũng chính là khởi đầu cho việc triển khai micro service ở Gcalls.
2. Những đặc điểm Clean Architecture ở Gcalls
Kiến trúc Clean Architecture được áp dụng ở nhiều service trong Gcalls. Một ví dụ về Clean Architecture ở User Service.

Ở đây ta có thể thấy cấu trúc thư mục của User Service được chia thành các lớp:
- Entities: Model/
- Use Cases & Interface Adapters: Routes/
- Frameworks and Drivers: app.js
3. Những đặc điểm CQRS ở Gcalls
Service Driven
Một đặc điểm nổi bật của CQRS được áp dụng trong hệ thống Gcalls là Read and Write service.
Trong kiến trúc Gcalls, các service backend ở Data Processing Layer được chia thành 2 nhóm đảm nhận vai trò đọc và ghi riêng biệt:
Read Service:
- filterService
Write Service:
- commandService
- recordService
Tất cả các request đọc, lấy dữ liệu đều được chuyển hướng đến read services, ngược lại các request ghi, chỉnh sửa dữ liệu được chuyển hướng đến các write services.
Database Driven
Hệ thống Gcalls sử dụng tính năng Read Preference của mongoDB replica set để điều hướng các hoạt động đọc của ứng dụng.
Tùy chọn nearest cho phép điều hướng request đến database có trạng thái phù hợp nhất, bất kể database đó là primary hay secondary.
Url kết nối mongo bình thường
mongodb://{user}:{pass}@{mongo0},{mongo1},{mongo2}/{database}?replicaSet={replicaSet}&authSource=admin
Url kết nối mongo với option readPreference
mongodb://{user}:{pass}@{mongo0},{mongo1},{mongo2}/{database}?replicaSet={replicaSet}&authSource=admin&readPreference=nearest
4. Những đặc điểm Microservices ở Gcalls
API Gateway
Trong hệ thống Gcalls, accessService đảm nhận vai trò như một API Gateway. Tất cả các request từ các service khác đến các service backend đều phải thông qua accessService. API Gateway sẽ nhận các requests đó, xác thực và điều hướng chúng đến các API cụ thể trên các services phía sau.
Tương tự các service backend muốn kết nối với nhau phải đi qua accessService.

Service per Domain
Các module trong Gcalls được chia thành các service nhỏ (microservice). Mỗi service đảm nhận một vai trò riêng và được đặt trên một server riêng.

Ở mô hình micro service các service đặc trên các server riêng biệt giúp dễ dàng để nâng cấp và scale ứng dụng.

Database per Service
Ở mô hình này mỗi write service được kết nối tới một database của riêng nó.
III. Kết Luận
Trên đây là tổng quan về công nghệ back end được áp dụng trong hệ thống Gcalls. Nếu có câu hỏi nào vui lòng điền vào form bên dưới.